﻿namespace Sai.Test.Sandcastle
{
	using System.IO;
	using Sai.Core.Sandcastle;
	using Xunit;
    using Sai.Test.XUnit;

	public class ContentLayoutFacts
	{
		public class TheToXmlMethod
		{
			[Fact, InMemoryTest]
			public void EmptyList_Creates_SingleLine_Format()
			{
				var contentLayout = new ContentLayout();

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					contentLayout.SaveTo(writer);
					text = writer.ToString();
				}

				Assert.Contains("<Topics />", text);
			}

			
			[Fact, InMemoryTest]
			public void Creates_MultiLine_Format()
			{
				var contentLayout = new ContentLayout();
				contentLayout.Add(new Topic("12345", "Help1"));
				contentLayout.Add(new Topic("23456", "Help2"));
				contentLayout.Add(new Topic("34567", "Help3"));
				contentLayout.Add(new Topic("45678", "Help4"));
				contentLayout.Add(new Topic("56789", "Help5"));

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					contentLayout.SaveTo(writer);
					text = writer.ToString();
				}

				Assert.Contains("<Topics>", text);
				Assert.Contains("<Topic id=\"12345\" title=\"Help1\" />", text);
				Assert.Contains("<Topic id=\"23456\" title=\"Help2\" />", text);
				Assert.Contains("<Topic id=\"34567\" title=\"Help3\" />", text);
				Assert.Contains("<Topic id=\"45678\" title=\"Help4\" />", text);
				Assert.Contains("<Topic id=\"56789\" title=\"Help5\" />", text);
				Assert.Contains("</Topics>", text);
			}

			
			[Fact, InMemoryTest]
			public void MultiLevel_Creates_Nested_Format()
			{
				var topLevelTopic = new Topic("01234", "Top");
				topLevelTopic.Add(new Topic("12345", "Help1"));
				topLevelTopic.Add(new Topic("23456", "Help2"));
				topLevelTopic.Add(new Topic("34567", "Help3"));
				topLevelTopic.Add(new Topic("45678", "Help4"));
				topLevelTopic.Add(new Topic("56789", "Help5"));
				
				var contentLayout = new ContentLayout();
				contentLayout.Add(topLevelTopic);

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					contentLayout.SaveTo(writer);
					text = writer.ToString();
				}

				Assert.Contains("<Topics>", text);
				Assert.Contains("<Topic id=\"01234\" title=\"Top\">", text);
				Assert.Contains("<Topic id=\"12345\" title=\"Help1\" />", text);
				Assert.Contains("<Topic id=\"23456\" title=\"Help2\" />", text);
				Assert.Contains("<Topic id=\"34567\" title=\"Help3\" />", text);
				Assert.Contains("<Topic id=\"45678\" title=\"Help4\" />", text);
				Assert.Contains("<Topic id=\"56789\" title=\"Help5\" />", text);
				Assert.Contains("</Topic>", text);
				Assert.Contains("</Topics>", text);
			}
		}

		public class TheLoadFromMethod
		{
			
			[Fact, InMemoryTest]
			public void Can_Load_Saved_Document()
			{
				var topLevelTopic = new Topic("01234", "Top");
				topLevelTopic.Add(new Topic("12345", "Help1"));
				topLevelTopic.Add(new Topic("23456", "Help2"));
				topLevelTopic.Add(new Topic("34567", "Help3"));
				topLevelTopic.Add(new Topic("45678", "Help4"));
				topLevelTopic.Add(new Topic("56789", "Help5"));

				ContentLayout originalVersion = new ContentLayout();
				originalVersion.Add(topLevelTopic);

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					originalVersion.SaveTo(writer);
					text = writer.ToString();
				}

				ContentLayout newVersion = null; // new ContentLayout();

				using (var reader = new StringReader(text))
				{
					newVersion = ContentLayout.LoadFrom(reader);
				}
			}
		}

		public class TheFindAndReplaceMethod
		{
			
			[Fact, InMemoryTest]
			public void Replaces_Child_Content_Of_Single_Node()
			{
				var topLevelTopic = new Topic("01234", "Top");
				topLevelTopic.Add(new Topic("12345", "Help1"));
				topLevelTopic.Add(new Topic("23456", "Help2"));
				topLevelTopic.Add(new Topic("34567", "Help3"));
				topLevelTopic.Add(new Topic("45678", "Help4"));
				topLevelTopic.Add(new Topic("56789", "Help5"));

				ContentLayout originalVersion = new ContentLayout();
				originalVersion.Add(topLevelTopic);

				var newVersion = new Topic("01234", "Top");
				newVersion.Add(new Topic("abcde", "Help-1"));
				newVersion.Add(new Topic("bcdef", "Help-2"));
				newVersion.Add(new Topic("cdefg", "Help-3"));
				newVersion.Add(new Topic("defgh", "Help-4"));
				newVersion.Add(new Topic("efghi", "Help-5"));

				originalVersion.FindAndReplace("01234", newVersion);

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					originalVersion.SaveTo(writer);
					text = writer.ToString();
				}

				Assert.Contains("01234", text);
				Assert.Contains("Top", text);

				Assert.Contains("abcde", text);
				Assert.Contains("bcdef", text);
				Assert.Contains("cdefg", text);
				Assert.Contains("defgh", text);
				Assert.Contains("efghi", text);

				Assert.Contains("Help-1", text);
				Assert.Contains("Help-2", text);
				Assert.Contains("Help-3", text);
				Assert.Contains("Help-4", text);
				Assert.Contains("Help-5", text);

				Assert.DoesNotContain("12345", text);
				Assert.DoesNotContain("23456", text);
				Assert.DoesNotContain("34567", text);
				Assert.DoesNotContain("45678", text);
				Assert.DoesNotContain("56789", text);

				Assert.DoesNotContain("Help1", text);
				Assert.DoesNotContain("Help2", text);
				Assert.DoesNotContain("Help3", text);
				Assert.DoesNotContain("Help4", text);
				Assert.DoesNotContain("Help5", text);
			}

			
			[Fact, InMemoryTest]
			public void Nodes_Unaltered_For_Missing_Guid()
			{
				var topLevelTopic = new Topic("01234", "Top");
				topLevelTopic.Add(new Topic("12345", "Help1"));
				topLevelTopic.Add(new Topic("23456", "Help2"));
				topLevelTopic.Add(new Topic("34567", "Help3"));
				topLevelTopic.Add(new Topic("45678", "Help4"));
				topLevelTopic.Add(new Topic("56789", "Help5"));

				ContentLayout originalVersion = new ContentLayout();
				originalVersion.Add(topLevelTopic);

				var newVersion = new Topic("999", "Top");
				newVersion.Add(new Topic("abcde", "Help-1"));
				newVersion.Add(new Topic("bcdef", "Help-2"));
				newVersion.Add(new Topic("cdefg", "Help-3"));
				newVersion.Add(new Topic("defgh", "Help-4"));
				newVersion.Add(new Topic("efghi", "Help-5"));

				originalVersion.FindAndReplace("999", newVersion);

				string text = string.Empty;

				using (var writer = new StringWriter())
				{
					originalVersion.SaveTo(writer);
					text = writer.ToString();
				}

				Assert.Contains("01234", text);
				Assert.Contains("Top", text);

				Assert.DoesNotContain("abcde", text);
				Assert.DoesNotContain("bcdef", text);
				Assert.DoesNotContain("cdefg", text);
				Assert.DoesNotContain("defgh", text);
				Assert.DoesNotContain("efghi", text);

				Assert.DoesNotContain("Help-1", text);
				Assert.DoesNotContain("Help-2", text);
				Assert.DoesNotContain("Help-3", text);
				Assert.DoesNotContain("Help-4", text);
				Assert.DoesNotContain("Help-5", text);

				Assert.Contains("12345", text);
				Assert.Contains("23456", text);
				Assert.Contains("34567", text);
				Assert.Contains("45678", text);
				Assert.Contains("56789", text);

				Assert.Contains("Help1", text);
				Assert.Contains("Help2", text);
				Assert.Contains("Help3", text);
				Assert.Contains("Help4", text);
				Assert.Contains("Help5", text);
			}
		}
	}
}
